package indi.cyh.config;


import indi.cyh.dao.InterfaceRequestLogMapper;
import indi.cyh.entity.InterfaceRequestLog;
import indi.cyh.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.UUID;

/**
 * @author CYH
 * @className GlobalExceptionHandler
 * @description 全局异常捕获
 * @date 2024/12/03 11:27
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @Autowired
    InterfaceRequestLogMapper logMapper;

    /**
     * 捕获参数异常
     *
     * @param exception MethodArgumentNotValidException
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public Response<String> argumentException(MethodArgumentNotValidException exception) {
        String result = "";
        //查看MethodArgumentNotValidException类可以发现,异常的信息在BindingResult下List<ObjectError>中
        //我这里取第一条的信息进行展示,可根据实际项目情况自行修改
        //getDefaultMessage()获取的信息就是我们RequestVerificationCode中的message部分
        exception.getBindingResult().getAllErrors();
        if (!exception.getBindingResult().getAllErrors().isEmpty()) {
            result = exception.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        }
        String parameterName = exception.getParameter().getParameterName();
        //自定义的返回类,可根据实际项目情况自行修改
        Response<String> returnMsg = new Response<>();
        returnMsg.setMessage(String.format("请求参数(%s)校验未通过:", parameterName) + result);
        return returnMsg;
    }

    /**
     * 所有异常通用处理
     *
     * @param e
     * @param webRequest
     * @return org.springframework.http.ResponseEntity<java.lang.Object>
     * @author CYH
     * @date 2025/1/20 14:16
     **/
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> runtimeExceptionProcess(Exception e, WebRequest webRequest) {
        log.error(e.getMessage());
        e.printStackTrace();
        Response<String> returnMsg = new Response<>();
        returnMsg.setStatus("-1");
        returnMsg.setMessage("接口调用异常:" + e.getMessage());
        return getResponseEntity(e, returnMsg, webRequest);
    }

    /**
     * 根据各种异常构建 ResponseEntity 实体. 服务于以上各种异常
     *
     * @param e
     * @param request
     * @return
     */
    private ResponseEntity<Object> getResponseEntity(Exception e, Response<String> returnMsg, WebRequest request) {
        e.printStackTrace();
        return handleExceptionInternal(e, returnMsg,
                new HttpHeaders(), HttpStatus.OK, request);
    }

    private ResponseEntity<Object> handleExceptionInternal(Exception ex, @Nullable Object body, HttpHeaders headers,
                                                           HttpStatus status, WebRequest request) {
        if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
            request.setAttribute("javax.servlet.error.exception", ex, 0);
        }

        return new ResponseEntity(body, headers, status);
    }
}
